const MenuModel = require('../models/menuModel');
const { logAudit } = require('../utils/auditLogger');
const { getLogger } = require('../logger');
const { generateCacheKey } = require('../cache/utils/cacheKeyGenerator');
const logger = getLogger('controllers.menuController');
const { success, error, serverError, notFound, badRequest } = require('../utils/response');
const { validateRequired, validateId, validateArray } = require('../utils/validator');
const cacheService = require('../cache/cacheService');

// 获取所有菜单
const getAllMenus = async (req, res) => {
    try {
        const page = parseInt(req.query.page) || 1;
        const limit = parseInt(req.query.limit) || 10;
        // 构建过滤条件
        const filters = {};
        const currentUserId = req.user.id;
        
        if (req.query.name) filters.name = req.query.name;
        if (req.query.menu_code) filters.module_code = req.query.menu_code;
        if (req.query.node_type !== undefined) filters.node_type = parseInt(req.query.node_type);
        if (req.query.parent_id !== undefined) filters.parent_id = parseInt(req.query.parent_id);
        if (req.query.status !== undefined) filters.status = parseInt(req.query.status);

        const menus = await MenuModel.getAllMenus(page,limit,filters,currentUserId);
        success(req, res, '获取菜单列表成功', menus);
    } catch (err) {
        logger.error('获取菜单列表错误', { error: err });
        serverError(req, res, '获取菜单列表失败');
    }
};

// 获取菜单树结构
const getMenuTree = async (req, res) => {
    
    try {
        const tree = await MenuModel.getMenuTree(req.user.id);
        success(req, res, '获取菜单树结构成功', tree);
    } catch (err) {
        logger.error('获取菜单树结构错误', { error: err });
        serverError(req, res, '获取菜单树结构失败');
    }
};

// 获取菜单详情
const getMenu = async (req, res) => {
    const { id } = req.params;
    
    try {
        if (!validateId(id)) {
            return badRequest(req, res, '菜单ID格式错误');
        }

        const menu = await MenuModel.findById(id);
        if (!menu) {
            return notFound(req, res, '菜单不存在');
        }

        success(req, res, '获取菜单信息成功', menu);
    } catch (err) {
        logger.error('获取菜单信息错误', { error: err });
        serverError(req, res, '获取菜单信息失败');
    }
};

// 创建菜单
const createMenu = async (req, res) => {
    const { name, module_code, access_type, is_show, node_type, icon, component_path, route_path, parent_id, code } = req.body;
    
    try {
        // 输入验证
        const requiredValidation = validateRequired(req.body, ['name','module_code', 'node_type']);
        if (!requiredValidation.isValid) {
            return badRequest(req, res, requiredValidation.message);
        }


        // 验证节点类型
        if (![1, 2, 3].includes(parseInt(node_type))) {
            return badRequest(req, res, '节点类型只能是1(目录)、2(菜单)或3(子页面)');
        }

        // 如果提供了父级ID，验证父级菜单是否存在
        if (parent_id) {
            if (!validateId(parent_id)) {
                return badRequest(req, res, '父级菜单ID格式错误');
            }
            
            const parentMenu = await MenuModel.findById(parent_id);
            if (!parentMenu) {
                return badRequest(req, res, '父级菜单不存在');
            }
        }

        // 检查模块编码是否已存在
        if (module_code) {
            const codeExists = await MenuModel.isModuleCodeExists(module_code);
            if (codeExists) {
                return badRequest(req, res, '菜单编码已存在');
            }
        }

        // 检查名称是否已存在
        const nameExists = await MenuModel.isNameExists(name);
        if (nameExists) {
            return badRequest(req, res, '菜单名称已存在');
        }

        // 创建菜单
        const newMenu = {
            name,
            module_code,
            access_type,
            is_show,
            node_type: parseInt(node_type),
            icon,
            component_path,
            route_path,
            parent_id: parent_id ? parseInt(parent_id) : null,
            code
        };

        const menuId = await MenuModel.create(newMenu);
        
        await logAudit(req, {
            action_type: 'create',
            module_code: 'menu',
            business_type: 'menu',
            operation_desc: 'create',
            target_entity_type: 'menu',
            target_entity_id: menuId,
            target_entity_name: name,
            after_data: newMenu
        });
        success(req, res, '菜单创建成功', {
            id: menuId,
            name,
            node_type: parseInt(node_type),
            icon,
            component_path,
            route_path,
            parent_id: parent_id ? parseInt(parent_id) : null
        });
    } catch (err) {
        logger.error('创建菜单错误', { error: err });
        serverError(req, res, '创建菜单失败');
    }
};

// 更新菜单
const updateMenu = async (req, res) => {
    const { id } = req.params;
    const { name, module_code, code, node_type, icon, component_path, route_path, parent_id, status } = req.body;
    
    try {
        if (!validateId(id)) {
            return badRequest(req, res, '菜单ID格式错误');
        }

        // 检查菜单是否存在
        const existingMenu = await MenuModel.findById(id);
        if (!existingMenu) {
            return notFound(req, res, '菜单不存在');
        }

        // 验证节点类型
        if (node_type !== undefined && ![1, 2, 3].includes(parseInt(node_type))) {
            return badRequest(req, res, '节点类型只能是1(目录)、2(菜单)或3(按钮)');
        }

        // 如果提供了父级ID，验证父级菜单是否存在且不能是自己
        if (parent_id !== undefined) {
            if (parent_id && !validateId(parent_id)) {
                return badRequest(req, res, '父级菜单ID格式错误');
            }
            
            if (parent_id && parseInt(parent_id) === parseInt(id)) {
                return badRequest(req, res, '不能将自己设为父级菜单');
            }
            
            if (parent_id) {
                const parentMenu = await MenuModel.findById(parent_id);
                if (!parentMenu) {
                    return badRequest(req, res, '父级菜单不存在');
                }
                
                // 检查是否会形成循环引用
                const allChildren = await MenuModel.getAllChildren(id);
                const childIds = allChildren.map(child => child.id);
                if (childIds.includes(parseInt(parent_id))) {
                    return badRequest(req, res, '不能将子菜单设为父级菜单');
                }
            }
        }

        // 如果提供了新的编码，检查是否重复
        if (code && code !== existingMenu.code) {
            const codeExists = await MenuModel.isCodeExists(code, id);
            if (codeExists) {
                return badRequest(req, res, '菜单编码已存在');
            }
        }

        // 如果提供了新的名称，检查是否重复
        if (name && name !== existingMenu.name) {
            const nameExists = await MenuModel.isNameExists(name, id);
            if (nameExists) {
                return badRequest(req, res, '菜单名称已存在');
            }
        }

        // 更新菜单信息
        const updateData = {
            name: name || existingMenu.name,
            module_code: module_code || existingMenu.module_code,
            code: code || existingMenu.code,
            node_type: node_type !== undefined ? parseInt(node_type) : existingMenu.node_type,
            icon: icon || existingMenu.icon,
            component_path: component_path || existingMenu.component_path,
            route_path: route_path || existingMenu.route_path,
            parent_id: parent_id !== undefined ? (parent_id ? parseInt(parent_id) : null) : existingMenu.parent_id,
            status: status !== undefined ? parseInt(status) : existingMenu.status
        };

        const affectedRows = await MenuModel.update(id, updateData);
        
        if (affectedRows > 0) {
            const updatedMenu = await MenuModel.findById(id);
            await logAudit(req, {
                action_type: 'update',
                module_code: 'menu',
                business_type: 'menu',
                operation_desc: 'update',
                target_entity_type: 'menu',
                target_entity_id: id,
                target_entity_name: updatedMenu.name,
                before_data: existingMenu,
                after_data: updatedMenu
            });
            success(req, res, '菜单更新成功', updatedMenu);
        } else {
            serverError(req, res, '菜单更新失败');
        }
    } catch (err) {
        logger.error('更新菜单错误', { error: err });
        serverError(req, res, '更新菜单失败');
    }
};

// 删除菜单
const removeMenu = async (req, res) => {
    const { id } = req.params;
    
    try {
        if (!validateId(id)) {
            return badRequest(req, res, '菜单ID格式错误');
        }

        // 检查菜单是否存在
        const existingMenu = await MenuModel.findById(id);
        if (!existingMenu) {
            return notFound(req, res, '菜单不存在');
        }

        // 检查菜单是否可以删除
        const deletable = await MenuModel.isDeletable(id);
        if (!deletable) {
            return badRequest(req, res, '该菜单下还有子菜单或已绑定角色，无法删除');
        }

        // 删除菜单
        const affectedRows = await MenuModel.deleteById(id);
        
        if (affectedRows > 0) {
            await logAudit(req, {
                action_type: 'delete',
                module_code: 'menu',
                business_type: 'menu',
                operation_desc: 'delete',
                target_entity_type: 'menu',
                target_entity_id: id,
                target_entity_name: existingMenu.name,
                before_data: existingMenu
            });
            success(req, res, '菜单删除成功');
        } else {
            serverError(req, res, '菜单删除失败');
        }
    } catch (err) {
        logger.error('删除菜单错误', { error: err });
        serverError(req, res, '删除菜单失败');
    }
};

// 获取子菜单
const getChildrenMenus = async (req, res) => {
    const { id } = req.params;
    
    try {
        if (!validateId(id)) {
            return badRequest(req, res, '菜单ID格式错误');
        }

        const children = await MenuModel.findByParentId(id);
        success(req, res, '获取子菜单成功', children);
    } catch (err) {
        logger.error('获取子菜单错误', { error: err });
        serverError(req, res, '获取子菜单失败');
    }
};

// 获取所有子菜单（包括子子菜单）
const getAllChildrenMenus = async (req, res) => {
    const { id } = req.params;
    
    try {
        if (!validateId(id)) {
            return badRequest(req, res, '菜单ID格式错误');
        }

        const children = await MenuModel.getAllChildren(id);
        success(req, res, '获取所有子菜单成功', children);
    } catch (err) {
        logger.error('获取所有子菜单错误', { error: err });
        serverError(req, res, '获取所有子菜单失败');
    }
};

// 获取父菜单
const getParentMenus = async (req, res) => {
    const { id } = req.params;
    
    try {
        if (!validateId(id)) {
            return badRequest(req, res, '菜单ID格式错误');
        }

        const parents = await MenuModel.getAllParents(id);
        success(req, res, '获取父菜单成功', parents);
    } catch (err) {
        logger.error('获取父菜单错误', { error: err });
        serverError(req, res, '获取父菜单失败');
    }
};


// 根据用户ID获取菜单
const getMenusByUserId = async (req, res) => {
    const { id } = req.params;
    if(!id){
        id = req.user?.id;
    }
    try {
        if (!validateId(id)) {
            return badRequest(req, res, '用户ID格式错误');
        }

        // 生成缓存键
        const cacheKey = generateCacheKey('menu', 'list', `user_${id}`, 'full');
        
        // 尝试从缓存获取数据
        const cachedMenus = await cacheService.get(cacheKey);
        if (cachedMenus) {
            logger.info('从缓存获取用户菜单', { userId: id });
            return success(req, res, '获取用户菜单成功', cachedMenus);
        }

        const menus = await MenuModel.findMenusByUserId(id,true);
        
        // 将结果存入缓存
        await cacheService.set(cacheKey, menus);
        logger.info('将用户菜单存入缓存', { userId: id });
        
        success(req, res, '获取用户菜单成功', menus);
    } catch (err) {
        logger.error('获取用户菜单错误', { error: err });
        serverError(req, res, '获取用户菜单失败');
    }
};

// 获取菜单统计信息
const getMenuStats = async (req, res) => {
    try {
        const stats = await MenuModel.getMenuStats();
        success(req, res, '获取菜单统计信息成功', stats);
    } catch (err) {
        logger.error('获取菜单统计信息错误', { error: err });
        serverError(req, res, '获取菜单统计信息失败');
    }
};

// 检查菜单是否可以删除
const checkMenuDeletable = async (req, res) => {
    const { id } = req.params;
    
    try {
        if (!validateId(id)) {
            return badRequest(req, res, '菜单ID格式错误');
        }

        const deletable = await MenuModel.isDeletable(id);
        
        success(req, res, '检查菜单删除状态成功', {
            deletable,
            message: deletable ? '可以删除' : '不能删除，该菜单下有子菜单或已绑定角色'
        });
    } catch (err) {
        logger.error('检查菜单删除状态错误', { error: err });
        serverError(req, res, '检查菜单删除状态失败');
    }
};

// 更新菜单排序
const updateMenuSort = async (req, res) => {
    const { id } = req.params;
    const { sort } = req.body;
    
    try {
        if (!validateId(id)) {
            return badRequest(req, res, '菜单ID格式错误');
        }

        if (sort === undefined || isNaN(parseInt(sort))) {
            return badRequest(req, res, '排序值必须是数字');
        }

        // 检查菜单是否存在
        const existingMenu = await MenuModel.findById(id);
        if (!existingMenu) {
            return notFound(req, res, '菜单不存在');
        }

        // 更新菜单排序
        const affectedRows = await MenuModel.updateSort(id, parseInt(sort));
        
        if (affectedRows > 0) {
            const updatedMenu = await MenuModel.findById(id);
            await logAudit(req, {
                action_type: 'update',
                module_code: 'menu',
                business_type: 'menu',
                operation_desc: 'update_sort',
                target_entity_type: 'menu',
                target_entity_id: id,
                target_entity_name: updatedMenu.name,
                before_data: { sort: existingMenu.sort },
                after_data: { sort: updatedMenu.sort }
            });
            success(req, res, '菜单排序更新成功', { sort: updatedMenu.sort });
        } else {
            serverError(req, res, '菜单排序更新失败');
        }
    } catch (err) {
        logger.error('更新菜单排序错误', { error: err });
        serverError(req, res, '更新菜单排序失败');
    }
};

// 批量更新菜单排序
const batchUpdateMenuSort = async (req, res) => {
    const { menuSorts } = req.body;
    
    try {
        if (!Array.isArray(menuSorts) || menuSorts.length === 0) {
            return badRequest(req, res, '菜单排序列表不能为空');
        }

        // 验证每个排序项
        for (const item of menuSorts) {
            if (!item.id || item.sort === undefined || isNaN(parseInt(item.sort))) {
                return badRequest(req, res, '排序项格式错误，必须包含有效的id和sort字段');
            }
            if (!validateId(item.id)) {
                return badRequest(req, res, `菜单ID ${item.id} 格式错误`);
            }
        }

        // 检查所有菜单是否存在
        for (const item of menuSorts) {
            const menu = await MenuModel.findById(item.id);
            if (!menu) {
                return notFound(req, res, `菜单ID ${item.id} 不存在`);
            }
        }

        // 批量更新排序
        const affectedCount = await MenuModel.batchUpdateSort(
            menuSorts.map(item => ({
                id: parseInt(item.id),
                sort: parseInt(item.sort)
            }))
        );
        
        if (affectedCount > 0) {
            await logAudit(req, {
                action_type: 'batch_update',
                module_code: 'menu',
                business_type: 'menu',
                operation_desc: 'batch_update_sort',
                target_entity_type: 'menu',
                after_data: { menuSorts }
            });
            success(req, res, '批量更新菜单排序成功', { affectedCount });
        } else {
            serverError(req, res, '批量更新菜单排序失败');
        }
    } catch (err) {
        logger.error('批量更新菜单排序错误', { error: err });
        serverError(req, res, '批量更新菜单排序失败');
    }
};

module.exports = {
    getAllMenus,
    getMenuTree,
    getMenu,
    createMenu,
    updateMenu,
    removeMenu,
    getChildrenMenus,
    getAllChildrenMenus,
    getParentMenus,
    getMenusByUserId,
    getMenuStats,
    checkMenuDeletable,
    updateMenuSort,
    batchUpdateMenuSort
};